[レポート] マルチ AZ 構成でさらに高度な回復力を持たせる方法 – グレーな障害を軽減するワークショップに参加しました / Advanced multi-AZ resilience patterns: Mitigating gray failures #reinvent #ARC201-R1
はじめに
こんにちは、降りしきる雨の中でもポケモン GO のギフトをせっせと集める Classmethod Canada の Funa です。今回はマルチ AZ 構成で見つけることが難しい「グレーな障害」を検知して対応するワークショップに参加したため、その内容をレポートしたいと思います。
ワークショップ概要
Many customer run their workloads in highly available, multi-Availability Zone (AZ) configurations. These architectures perform well during binary failure events, but often encounter problems with "gray failures". These types of failures' manifestations can be subtle and defy quick and definitive detection. This workshop will demonstrate 1/how you can use services like Amazon CloudWatch to detect gray failures and 2/the use of two mitigation patterns to respond to them.
日本語化したものはこちらです。
多くのお客様は、高可用性のマルチ AZ 構成でワークロードを実行しています。これらのアーキテクチャは、バイナリ障害イベント中にうまく機能しますが、「グレーな障害」で問題が発生することがよくあります。これらのタイプの障害の兆候はわずかであり、迅速かつ確実な検出が困難な場合があります。このワークショップでは、① Amazon CloudWatch などのサービスを使用してグレーな障害を検出する方法と、② 2 つの軽減パターンを使用してそれらに対応する方法を示します。
ワークショップ資料
- Workshop Studio: Advanced Multi-AZ Resilience Patterns
-
ドキュメント(ホワイトペーパー): https://docs.aws.amazon.com/ja_jp/whitepapers/latest/advanced-multi-az-resilience-patterns/advanced-multi-az-resilience-patterns.html
セッション内容
グレーな障害についての概要
「グレーな障害」とは
アプリがオブザーバを通じて障害の影響を認識しているが、基盤となるシステムが障害を認識せず (または影響がしきい値を超えるほど重大ではない)、リアクターが適切な軽減策をトリガーできないような障害を指します。
グレーな障害の例
例えば、システムを利用するアプリが 3 つあり、クライアント側でレイテンシーを計測しているとします。そしてオブザーバは全アプリの平均レイテンシーが閾値である 60 ms を超過したことを確認した際にリアクターが再起動などのアクションを取るという構成だとします。
アプリ 1 にてなんらかの問題が発生して、レイテンシーのメトリクスが 70 ms まで上昇した場合も、オブザーバで計測している全アプリの平均レイテンシーは 59.66 ms となってしまうため、アプリ 1 と 平均レイテンシー間で 40 % もの差が生まれていますが、閾値は超えていないために適切な対応をトリガーできません。
システム観点 VS アプリ観点での障害
このようにシステムの観点では Healthy ですが、アプリの観点では Unhealthy であるような障害が「グレーな障害」です。通常のヘルスチェックの観点からはインスタンスとデータベースの両方が正常であるように見えても、このタイプの障害は DNS 解決またはデータベースへの接続機能に影響を与える可能性があります。
AZ でのグレーな障害を検知する方法
検知に利用するツール
検知に利用する主なツールは以下の 2 つです。
- Amazon CloudWatch Contributor Insights
- 上位 N 位のコントリビューター、一意のコントリビューターの合計数、およびそれらの使用状況に関するメトリクスを確認できる
- パフォーマンスのボトルネック、最も重いトラフィックパターンなどを発見できる
- CloudWatch metric math が使用できる
- 自分で定義したルールとログとを比較する
- CloudWatch の複合アラーム
- 他のアラームの状態を監視する
- 他の複合アラームも監視することができる
- AND、OR、NOT といったシンプルな論理アラーム式
単一 AZ に影響を与えるグレーな障害を検知するアプローチ
単一 AZ に影響を与えるグレーな障害を検知するアプローチとしては、以下のような CloudWatch 複合アラームを作成することが考えられます。
詳細は ドキュメント をご参照ください。
AZ でのグレーな障害を軽減する方法
コントロールプレーンとデータプレーン
このワークショップでは 2 つの異なる回復パターンを扱います。それは AWS ではコントロールプレーンとデータプレーンを区別しているためです。
- コントロールプレーン
- システムへの変更 (リソースの追加、削除、変更など) に関連する操作
- 変更を有効にするために必要な場所にそれらの変更を伝搬させる必要がある
- ALB のネットワーク構成の更新や Lambda 関数の作成など
- 複雑
- 低ボリューム
--
- データプレーン
- 日常業務に関連する操作
- EC2 インスタンスの実行や、DynamoDB テーブルからのアイテムの取得など
- シンプル
- 高ボリューム
- 日常業務に関連する操作
ワークショップで使用するアーキテクチャ
従来の 3 層 Web アーキテクチャを使用します。
- プライベート VPC を採用(AWS サービスとの通信には VPC エンドポイントを使用)
- クロスゾーン負荷分散が無効になっている 3 つの AZ に分散された内部 NLB
- EC2 インスタンスの Auto Scaling グループ
- マルチ AZ の Aurora データベース (※ワークショップではコスト節約のためにデプロイされません)
AZ 退避パターン 1 - データプレーン
ヘルスチェックサーキットブレーカーを使用して、影響を受ける AZ に顧客のトラフィックがルーティングされないようにします。
- サービスのコントロールプレーンに影響がある場合でも利用可能
AZ 退避パターン 2 - コントロールプレーン
EC2 Auto Scaling グループの設定を更新して、影響を受ける AZ のサブネットを Auto Scaling グループのネットワーク構成から削除します。
- AZ 退避パターン 1 の対応後に実行する
ワークショップ内容
ワークショップを開始する前に
- ここからワークショップで使用するコンテンツをダウンロードします(content.zip)。
-
ローカルで zip を展開し、ワークショップを実行したいリージョンと同じリージョンにある S3 バケットにファイルをアップロードします。
- バケットポリシーで明示的にアクセスを拒否していないことを確認してください。
- content フォルダ配下のファイルを全てアップロードします。
- CloudFormation で
multi-az-workshop.template
ファイルを使用してスタックを起動します。- SourceBucket のパラメータに先ほどファイルをアップロードした S3 バケット名を入力します。
- ObjectKeyPrefix のパラメータは空白にします。
- スタックのステータスが CREATE_COMPLETE になるのを待ち、CloudWatch メトリクスがダッシュボードに出力されるのを待ちます(約 1 時間)。
※ かなりたくさんのリソースが作成されますので料金にご注意ください。
CloudWatch ダッシュボードを確認する
- CloudWatch コンソールにアクセスし、CloudWatch ダッシュボードを選択します。
- すると 4 つのカスタムダッシュボードが作成されています。
- Home Index API ダッシュボードを確認するために、
Home-Index-availability-and-latency-dashboard-【リージョン名】
を選択してください。 - ダッシュボードの各項目の説明につきましては、ここを参照ください。
単一の AZ に影響を与えるグレーな障害をシミュレートする
AWS Systems Manager を使用してシミュレートする
- AWS Systems Manager コンソールにアクセスし、ドキュメントを選択します。
- 自己所有タブをクリックし、
【スタック名】-SimulateFailureStack
ではじまるドキュメントを選択し、「オートメーションを実行する」をクリックします。
- 自己所有タブをクリックし、
- 特に何も変更せずにページの下部にある「実行」をクリックします。これで使用中の AZ がランダムに選択されて障害がシミュレートされます。
-
数分後にダッシュボードを更新したところ、Isolated Impact Aggregate Alarm の 1 つ (use1-az1) が ALARM 状態に移行したのが確認できました。
- また、サーバー側の可用性メトリックのグラフでも障害が表示されています。
- canary でもこの障害の影響を認識していることを確認できます。
Contributor Insights メトリクスを確認する
- Contributor Insights コンソールにアクセスし、障害がシミュレートされた AZ に対応するルールを開きます。
- 私の場合は
use1-az1
で障害がシミュレートされたのでuse1-az1-not-single-instance-failures
をクリックします。
- 私の場合は
- このグラフは、AZ 障害をシミュレートした直後に、2 つのインスタンスが 5xx HTTP 応答の報告を開始したことを示しています。これにより、影響が複数のインスタンスに及ぶことがわかります。
CloudWatch アラームを確認する
CloudWatch アラームにアクセスし、すべてのアラームを選択した後、 【対象の AZ】 Isolated Impact Aggregate Alarm
を確認します。
- アラームルールタブを選択すると、以下のようなルールが組まれていることが確認できます。
use1-az1
にて可用性またはレイテンシーへの影響が見られる場合はアラーム状態にする- なおかつ、1 つ以上のインスタンスで可用性またはレイテンシーの観点で影響が見られる
- なおかつ、その他の AZ では可用性またはレイテンシーへの影響はない
use1-az1 に関連するアラームの状態は以下のようになっています。
AZ 退避パターン 1 - データプレーン
影響を受ける AZ の DNS レコードが www.example.com
のクエリで返されないようにするヘルスチェックサーキットブレーカーを有効にします。実行される内容の詳細はここをご参照ください。
- AWS Systems Manager コンソールにアクセスし、ドキュメントを選択します。
- 自己所有タブをクリックし、
【スタック名】-HealthCheckCircuitBreakerStack
ではじまるドキュメントを選択し、「オートメーションを実行する」をクリックします。
- 自己所有タブをクリックし、
- 入力パラメータの AZ で先ほど障害をシミュレートした AZ を選択し、IsHealthy では false と入力して実行をクリックしてランブックが正常に完了するのを待ちます。
次に、CloudWatch メトリクスダッシュボードに戻り、影響が緩和されたかどうかを確認します。
- Isolated Impact Aggregate Alarm では、対象の AZ はアラーム状態のままです。
- AZ 固有のエンドポイントをテストしている canary も、まだ影響を受けていることが確認できます。
- リージョンエンドポイントをテストしている canary を確認してみます。
ヘルスチェックサーキットブレーカーを実行した後、リージョンエンドポイントの可用性がイベント前の値である 100% に戻り始めたことがわかります。したがって、ヘルスチェックサーキットブレーカーがカスタマーエクスペリエンスへの影響をうまく軽減したことがわかります。
AZ 退避パターン 2 - コントロールプレーン
次にコントロールプレーンアクションを利用して Auto Scaling グループのネットワーク構成を更新し、影響を受ける AZ に追加の容量がデプロイされないようにします。実行される内容の詳細はここをご参照ください。
- AWS Systems Manager コンソールにアクセスし、ドキュメントを選択します。
- 自己所有タブをクリックし、
【スタック名】-BigRedButtonStack
ではじまるドキュメントを選択し、「オートメーションを実行する」をクリックします。
- 自己所有タブをクリックし、
- 入力パラメータの Acrion では EVACUATE を選択し、AZ では障害をシミュレートした AZ を選択、ResourceType では AutoScalingGroup を選択して実行をクリックしてランブックが正常に完了するのを待ちます。
- AWS Resource Access Manager を開き、AZ ID がどの AZ 名になるかを確認します。
- 障害がシミュレートされている use1-az1 は us-east-1b であることがわかります。
- EC2 コンソールより、Auto Scaling グループをクリックし、名前に
FrontEndAutoScalingGroup
が含まれているグループを選択します。- ネットワークの項目を確認すると、ネットワーク構成が更新されて us-east-1b が退避されていることがわかります。
- EC2 インスタンスのページで、us-east-1b 上のインスタンスがすべて終了していることを確認できます。
これで、AZ の退避アクションが完了しました。
クリーンアップ
ワークショップを終了する際はコストを削減するために、環境のクリーンアップを忘れずに行ってください。詳細はこちらをご参照ください。
関連情報
異常な 1 AZ へのトラフィックを止め、正常な 2 AZ で処理を行わせ、その間に 1 AZ の原因解決を実施するためのゾーンシフト機能については、以下の弊社記事にも記載があります。
おわりに
家に帰ってから CloudFormation を使ってスタックの立ち上げをするのにかなり苦戦しました。リージョンによってはリソースのサービスクォータを超えていたり、作成されたサブネットがリソースに対応していなかったためです。リソースが大量に作成されるため、CloudTrail でのイベント情報が膨大で原因を把握するのも大変でした。ワークショップの内容はとても勉強になるものだったので、よければお試しいただければと思います!